package at.horario.web.component;

import org.apache.wicket.markup.html.WebPage;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.link.BookmarkablePageLink;
import org.apache.wicket.markup.html.link.Link;
import org.apache.wicket.markup.html.list.ListItem;
import org.apache.wicket.markup.html.list.ListView;
import org.apache.wicket.markup.html.panel.Fragment;
import org.apache.wicket.markup.html.panel.Panel;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.PropertyModel;
import org.apache.wicket.model.ResourceModel;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import at.horario.web.HorarioSession;

public class MenuPanel extends Panel {
    private static final long serialVersionUID = 1L;
    private final List<MenuItem> topMenuItems = new ArrayList<MenuItem>();
    public static final String LINK_ID = "linkid";
    public static final String LINK_TEXT_ID = "linktext";

    public MenuPanel(final String id) {
        super(id);
        add(new MenuListView("topmenuitems", new PropertyModel(this,
                "topMenuItems")));
    }

    /**
     * Add one menu item
     */
    public void addMenu(final MenuItem menu) {
        topMenuItems.add(menu);
    }

    /**
     * Add all menus at once
     */
    public void setMenuItems(final List<MenuItem> menuItems) {
        topMenuItems.clear();
        topMenuItems.addAll(menuItems);
    }

    public void addMenu(Class<? extends WebPage> pageClass) {
        if (((HorarioSession) getSession()).contem(pageClass))
            addMenu(new MenuItem(pageClass));
    }


    public static class MenuItem implements Serializable {
        private static final long serialVersionUID = 8198442375175693685L;

        private final Link link;
        private final String label;


        public MenuItem(final Class<? extends WebPage> pageClass) {
            this(new BookmarkablePageLink(MenuPanel.LINK_ID,
                    pageClass), pageClass.getSimpleName().toLowerCase());

        }

        public MenuItem(final Link link, final String label) {
            if (link != null && !link.getId().equals(LINK_ID)) {
                throw new IllegalArgumentException(
                        "The id must be LINK_ID");
            }
            this.link = link;
            this.link.add(new Label(LINK_TEXT_ID, new ResourceModel(label + ".link")));
            this.label = label;
        }

        public MenuItem(final String label) {
            link = null;
            this.label = label;
        }


        public Link getLink() {
            return link;
        }


        public String getLabel() {
            return label;
        }
    }


    private final class MenuItemFragment extends Fragment {
        private static final long serialVersionUID = 0L;

        public MenuItemFragment(final MenuItem menuItem) {
            super("menuitemfragment", "MENUITEMFRAGMENT",
                    MenuPanel.this);
            // Add the menu's label (hyperlinked if a link is provided)
            if (menuItem.getLink() != null) {
                add(new LinkFragment(menuItem.getLink(), menuItem.getLabel()));
            } else {
                add(new TextFragment(menuItem.getLabel()));
            }
        }
    }


    private final class LinkFragment extends Fragment {
        private static final long serialVersionUID = 0L;

        public LinkFragment(final Link link, final String label) {
            super("linkfragment", "LINKFRAGMENT", MenuPanel.this);
            add(link);
        }
    }

    private final class TextFragment extends Fragment {
        private static final long serialVersionUID = 0L;

        public TextFragment(final String label) {
            super("linkfragment", "TEXTFRAGMENT", MenuPanel.this);
            add(new Label(LINK_TEXT_ID, label));
        }
    }

    private final class MenuListView extends ListView {
        private static final long serialVersionUID = -5875124377225299067L;

        private MenuListView(final String id, final IModel model) {
            super(id, model);
        }

        private MenuListView(final String id, final List<MenuItem> list) {
            super(id, list);
        }

        @Override
        protected void populateItem(final ListItem item) {
            final MenuItem menuItem = (MenuItem) item.getModelObject();
            item.add(new MenuItemFragment(menuItem));
        }
    }


}